package com.gongzhiyun.springboot3test.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gongzhiyun.springboot3test.base.PageBean;
import com.gongzhiyun.springboot3test.base.R;
import com.gongzhiyun.springboot3test.entity.novel.*;
import com.gongzhiyun.springboot3test.entity.user.AuthInfo;
import com.gongzhiyun.springboot3test.interceptor.AppInterceptor;
import com.gongzhiyun.springboot3test.mapper.novel.*;
import com.gongzhiyun.springboot3test.service.NovelService;
import com.gongzhiyun.springboot3test.service.UserService;
import com.gongzhiyun.springboot3test.vo.ExInfo;
import com.gongzhiyun.springboot3test.vo.NovelCommentData;
import com.gongzhiyun.springboot3test.vo.NovelCommentReplyData;
import com.gongzhiyun.springboot3test.vo.NovelShelfData;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class NovelServiceImpl implements NovelService {
    private final NovelCommentMapper novelCommentMapper;
    private final NovelCommentReplyMapper novelCommentReplyMapper;
    private final NovelUserRatingsMapper novelUserRatingsMapper;
    private final NovelTypesMapper novelTypesMapper;
    private final NovelShelfMapper novelShelfMapper;
    private final NovelListMapper novelListMapper;
    private final NovelChapterMapper novelChapterMapper;
    private final NovelReadingMapper novelReadingMapper;
    private final UserService userService;
    private final NovelCommentPraisesMapper novelCommentPraisesMapper;
    private final NovelCommentReplyPraisesMapper novelCommentReplyPraisesMapper;


    /**
     * 查询最后一笔的小说id
     * @return
     */
    @Override
    public Integer getLastId() {
        return novelListMapper.getLastId();
    }

    /**
     * 通过id查询小说信息
     */
    @Override
    public R<NovelList> queryNovelById(Integer novelId) {
        NovelList novelList = novelListMapper.selectById(novelId);
        novelList.setTotalChapters(novelChapterMapper.getChapterCount(novelId));
        novelList.setRating(novelUserRatingsMapper.getAvgRating(novelId));
        return R.ok(novelList);
    }


    /**
     * 获取用户阅读记录
     *
     * @param novelId
     * @return
     */
    @Override
    public R<NovelReading> getReading(Integer novelId) {
        //获取认证信息
        AuthInfo authInfo = AppInterceptor.get();
        Integer uid = authInfo.getUid();
        if (uid == null) {
            return R.fail("用户未登录");
        }
        QueryWrapper<NovelReading> qw=new QueryWrapper<>();
        qw.eq("novel_id", novelId);
        qw.eq("user_id", uid);
        NovelReading novelReading=novelReadingMapper.selectOne(qw);
        return R.ok(novelReading);
    }


    /**
     * 获取登录用户的历史阅读进度
     *
     * @return
     */
    @Override
    public R<List<NovelShelfData>> getHistoryReading() {
        //获取认证信息
        AuthInfo authInfo = AppInterceptor.get();
        Integer uid = authInfo.getUid();
        if (uid == null) {
            return R.fail("用户未登录");
        }
        List<NovelReading> readingList = novelReadingMapper.getUserReading(uid);

        List<NovelShelfData> list = new ArrayList<>();
        readingList.forEach(i -> {
            NovelShelfData data = new NovelShelfData();
            data.setReading(i.getChapterId());
            data.setNovelId(i.getNovelId());
            data.setId(i.getId());
            data.setIsShelf(isShelf(i.getNovelId(), uid));

            NovelList novelList = novelListMapper.selectById(i.getNovelId());
            novelList.setTotalChapters(novelChapterMapper.getChapterCount(i.getNovelId()));
            data.setNovel(novelList);

            data.setUserId(uid);
            data.setLastupdate(i.getLastReadTime());
            list.add(data);
        });

        return R.ok(list);
    }


    /**
     * 更新和保存用户阅读记录
     *
     * @param novelReading
     * @return
     */
    @Override
    public R<String> saveReading(NovelReading novelReading) {
        //获取认证信息
        AuthInfo authInfo = AppInterceptor.get();
        Integer uid = authInfo.getUid();
        if (uid == null) {
            return R.fail("用户未登录");
        }
       QueryWrapper<NovelReading> qw = new QueryWrapper<>();
        qw.eq("novel_id", novelReading.getNovelId());
        qw.eq("user_id", uid);
        NovelReading check = novelReadingMapper.selectOne(qw);

        if (check == null) {
            novelReading.setUserId(uid);
            int i = novelReadingMapper.insert(novelReading);
            return i == 1 ? R.ok("加入阅读记录成功") : R.fail("加入阅读记录失败");
        } else {
            check.setChapterId(novelReading.getChapterId());
            int i = novelReadingMapper.updateById(check);
            return i == 1 ? R.ok("更新阅读记录成功") : R.fail("更新阅读记录失败");
        }

    }


    /**
     * 获取某部小说的所有章节数和标题
     *
     * @param novelId
     * @return
     */
    @Override
    public R<List<NovelChapter>> queryChapter(Integer novelId) {
        return R.ok(novelChapterMapper.queryChapter(novelId));
    }

    /**
     * 查询某个章节序号里的章节内容
     *
     * @param id
     * @return
     */
    @Override
    public R<NovelChapter> getChapter(Integer id, Integer novelId) {
        return R.ok(novelChapterMapper.getChapterContent(id, novelId));
    }

    /**
     * 用户查询小说列表操作
     *
     * @param novelList
     * @param pageBean
     * @return
     */
    @Override
    public R<List<NovelList>> queryNovel(NovelList novelList, PageBean pageBean) {
        //建立查询条件
        QueryWrapper<NovelList> qw = new QueryWrapper<>();
        if (novelList.getNovelTitle() != null && !novelList.getNovelTitle().isEmpty()) {
            qw.like("novel_title", novelList.getNovelTitle());
        }

        if (novelList.getAuthorName() != null && !novelList.getAuthorName().isEmpty()) {
            qw.like("author_name", novelList.getAuthorName());
        }

        if (novelList.getTypeId() != null && novelList.getTypeId() != 0) {
            qw.eq("type_id", novelList.getTypeId());
        }

        if (novelList.getStatus() != null && !novelList.getStatus().isEmpty()) {
            qw.eq("status", novelList.getStatus());
        }

        Page<NovelList> pages = novelListMapper.selectPage(new Page<>(pageBean.getPageNum(), pageBean.getPageSize()), qw);
        pageBean.setPages(pages.getPages());
        pageBean.setTotal(pages.getTotal());

        pages.getRecords().forEach(i -> {
            i.setRating(novelUserRatingsMapper.getAvgRating(i.getId()));
            i.setTotalChapters(novelChapterMapper.getChapterCount(i.getId()));
        });

        R<List<NovelList>> r = R.ok(pages.getRecords());
        r.setPageBean(pageBean);
        return r;
    }

    /**
     * 加入小说信息操作
     *
     * @param novelList
     * @return
     */
    @Override
    public R<String> joinNovel(NovelList novelList) {
        //获取登录认证信息


        NovelList check = novelListMapper.queryByTitle(novelList.getNovelTitle());
        if (check != null) {
            return R.fail("该小说名称已经存在");
        }

        int i = novelListMapper.insert(novelList);
        if (i != 1) {
            return R.fail("加入小说失败");
        }

        return R.ok("加入小说成功");

    }

    /**
     * 增加小说章节内容操作
     *
     * @param novelChapter
     * @return
     */
    @Override
    public R<String> joinChapter(NovelChapter novelChapter) {
        NovelChapter check = novelChapterMapper.queryChapterByTitle(novelChapter.getChapterTitle());
        if (check != null){
            return R.fail("改小说标题已经存在");
        }

        int i = novelChapterMapper.insert(novelChapter);
        if (i != 1) {
            return R.fail("加入章节失败");
        }
        return R.ok("加入章节成功");
    }


    /**
     * 查询登录用户的书架内容
     *
     * @return
     */
    @Override
    public R<List<NovelShelfData>> queryShelf() {
        //获取用户登录信息
        AuthInfo authInfo = AppInterceptor.get();
        Integer uid = authInfo.getUid();
        if (uid == null) {
            return R.fail("用户未登录");
        }
        List<NovelShelf> shelfList = novelShelfMapper.getUserShelf(uid);

        List<NovelShelfData> list = new ArrayList<>();
        shelfList.forEach(i -> {
            NovelShelfData data = new NovelShelfData();
            NovelList novelList = novelListMapper.selectById(i.getNovelId());
            novelList.setTotalChapters(novelChapterMapper.getChapterCount(i.getNovelId()));
            data.setReading(novelReadingMapper.getReading(i.getNovelId(), uid));
            data.setNovel(novelList);
            data.setUserId(i.getUserId());
            data.setNovelId(i.getNovelId());
            list.add(data);
        });

        return R.ok(list);
    }

    /**
     * 用户加入书架操作，需要登录
     *
     * @param novelId
     * @return
     */
    @Override
    public R<String> joinShelf(Integer novelId) {
        //检验小说存不存在
        if (novelListMapper.selectById(novelId) == null) {
            return R.fail("小说不存在");
        }

        //获取登录信息
        AuthInfo authInfo = AppInterceptor.get();
        Integer uid = authInfo.getUid();
        if (uid == null) {
            return R.fail("用户未登录");
        }
        NovelShelf novelShelf = novelShelfMapper.getShelf(novelId, uid);
        //用户未加入书架
        if (novelShelf == null) {
            novelShelf = new NovelShelf();
            novelShelf.setNovelId(novelId);
            novelShelf.setUserId(uid);
            int i = novelShelfMapper.insert(novelShelf);
            if (i != 1) {
                return R.fail("用户加入书架失败");
            }
            return R.ok("用户加入书架成功");
        }
        //用户已加入书架
        int i = novelShelfMapper.deleteById(novelShelf.getId());
        if (i != 1) {
            return R.fail("用户取消书架信息失败");
        }
        return R.ok("用户取消书架操作成功");
    }

    /**
     * 查询女生频道的小说类型
     *
     * @return
     */
    @Override
    public R<List<NovelTypes>> queryTypesF() {
        return R.ok(novelTypesMapper.getF());
    }

    /**
     * 查询男生频道的小说类型
     *
     * @return
     */
    @Override
    public R<List<NovelTypes>> queryTypesM() {
        return R.ok(novelTypesMapper.getM());
    }

    /**
     * 用户对某小说的评分操作，需要登录
     *
     * @param userRatings
     * @return
     */
    @Override
    public R<String> userRatings(NovelUserRatings userRatings) {
        Integer isExits = novelUserRatingsMapper.getRatingCount(userRatings.getNovelId());
        if (isExits > 0) {
            return R.fail("已经评分过不能在评分啦");
        }
        //获取用户认证信息
        AuthInfo authInfo = AppInterceptor.get();
        Integer uid = authInfo.getUid();
        if (uid == null) {
            return R.fail("用户未登录");
        }
        userRatings.setUserId(uid);

        int i = novelUserRatingsMapper.insert(userRatings);

        if (i != 1) {
            return R.fail("评分录入失败");
        }
        return R.ok("评分录入成功");
    }

    /**
     * 用户点赞某评论操作，需要登录
     *
     * @param commentId
     * @return
     */
    @Override
    public R<String> praiseComment(Integer commentId) {
        NovelComment novelComment = novelCommentMapper.selectById(commentId);
        if (novelComment == null) {
            return R.fail("评论不存在");
        }
        //获取登录用户信息
        AuthInfo authInfo = AppInterceptor.get();
        Integer uid = authInfo.getUid();
        if (uid == null) {
            return R.fail("请先登录");
        }
        NovelCommentPraises commentPraises = novelCommentPraisesMapper.isPraised(uid, commentId);
        //用户未点赞
        if (commentPraises == null) {
            commentPraises = new NovelCommentPraises();
            commentPraises.setCommentId(commentId);
            commentPraises.setUserId(uid);
            int i = novelCommentPraisesMapper.insert(commentPraises);
            if (i != 1) {
                return R.fail("用户新增点赞信息失败");
            }
            return R.ok("点赞成功");
        }
        //用户已点赞
        int i = novelCommentPraisesMapper.deleteById(commentPraises.getId());
        if (i != 1) {
            return R.fail("用户删除更新信息失败");
        }

        return R.ok("取消点赞成功");
    }

    /**
     * 用户点赞某评论回复操作,需要登录
     *
     * @param replyId
     * @return
     */
    @Override
    public R<String> praiseCommentReply(Integer replyId) {
        NovelCommentReply novelCommentReply = novelCommentReplyMapper.selectById(replyId);
        if (novelCommentReply == null) {
            return R.fail("回复不存在");
        }
        //获取登录用户信息
        AuthInfo authInfo = AppInterceptor.get();
        Integer uid = authInfo.getUid();
        if (uid == null) {
            return R.fail("请先登录");
        }
        NovelCommentReplyPraises replyPraises = novelCommentReplyPraisesMapper.isPraised(uid, replyId);
        //用户未点赞
        if (replyPraises == null) {
            replyPraises = new NovelCommentReplyPraises();
            replyPraises.setCommentReplyId(replyId);
            replyPraises.setUserId(uid);
            int i = novelCommentReplyPraisesMapper.insert(replyPraises);
            if (i != 1) {
                return R.fail("用户新增点赞信息失败");
            }
            return R.ok("点赞成功");
        }
        //用户已点赞
        int i = novelCommentReplyPraisesMapper.deleteById(replyPraises.getId());
        if (i != 1) {
            return R.fail("用户删除更新信息失败");
        }

        return R.ok("取消点赞成功");
    }

    /**
     * 查询某部小说的书评
     *
     * @param novelComment
     * @param pageBean
     * @return
     */
    @Override
    public R<List<NovelCommentData>> queryComment(NovelComment novelComment, PageBean pageBean) {
        //建立查询条件
        QueryWrapper<NovelComment> qw = new QueryWrapper<>();
        if (novelComment.getNovelId() != null && novelComment.getNovelId() != 0) {
            qw.eq("novel_id", novelComment.getNovelId());
        }

        //order==1为最新排序，order==2为最热排序,默认为最热排序
        switch (pageBean.getOrder()) {
            case 1:
                qw.orderByDesc("create_time");
            case 2:
                qw.orderByDesc("praise");
            default:
                qw.orderByDesc("praise");
        }
        //执行分页查询
        Page<NovelComment> pages = novelCommentMapper.selectPage(new Page<>(pageBean.getPageNum(), pageBean.getPageSize()), qw);
        pageBean.setTotal(pages.getTotal());
        pageBean.setPages(pages.getPages());
        List<NovelCommentData> list = new ArrayList<>();

        pages.getRecords().forEach(i -> {
            NovelCommentData data = new NovelCommentData();
            data.setId(i.getId());
            data.setNovelId(i.getNovelId());
            data.setUserId(i.getUserId());
            data.setContent(i.getContent());
            data.setCreateTime(i.getCreateTime());
            data.setPraise(novelCommentPraisesMapper.getCommentPraiseCount(i.getId()));
            data.setReply(getCommentReplyCount(i.getId()));
            data.setNovel(novelListMapper.selectById(i.getNovelId()));
            data.setUser(userService.queryByIdAll(i.getUserId()).viewData());
            data.setExInfo(getCommentExInfo(i.getUserId(), i.getId()));
            list.add(data);
        });
        R<List<NovelCommentData>> r = R.ok(list);
        r.setPageBean(pageBean);
        return r;
    }

    /**
     * 查询某部小说的评论的回复内容
     */
    @Override
    public R<List<NovelCommentReplyData>> queryReply(NovelCommentReply novelCommentReply, PageBean pageBean) {
        //建立查询条件
        QueryWrapper<NovelCommentReply> qw = new QueryWrapper<>();
        if (novelCommentReply.getNovelId() != null && novelCommentReply.getNovelId() != 0) {
            qw.eq("novel_id", novelCommentReply.getNovelId());
        }
        qw.eq("comment_id", novelCommentReply.getCommentId());
        qw.orderByDesc("create_time");

        //执行查询语句
        Page<NovelCommentReply> pages = novelCommentReplyMapper.selectPage(new Page<>(pageBean.getPageNum(), pageBean.getPageSize()), qw);
        pageBean.setTotal(pages.getTotal());
        pageBean.setPages(pages.getPages());

        List<NovelCommentReplyData> list = new ArrayList<>();
        pages.getRecords().forEach(i -> {
            NovelCommentReplyData data = new NovelCommentReplyData();
            data.setId(i.getId());
            data.setNovelId(i.getNovelId());
            data.setUserId(i.getUserId());
            data.setCommentId(i.getCommentId());
            data.setContent(i.getContent());
            data.setCreateTime(i.getCreateTime());
            data.setPraise(novelCommentReplyPraisesMapper.getReplyPraiseCount(i.getId()));

            data.setUser(userService.queryByIdAll(i.getUserId()).viewData());
            data.setExInfo(getReplyExInfo(i.getUserId(), i.getId()));

            list.add(data);
        });

        R<List<NovelCommentReplyData>> r = R.ok(list);
        r.setPageBean(pageBean);
        return r;
    }

    /**
     * 发布小说评论，需要登录
     *
     * @param novelComment
     * @return
     */
    @Override
    public R<String> comment(NovelComment novelComment) {
        //获取登录的认证信息
        AuthInfo authInfo = AppInterceptor.get();
        Integer uid = authInfo.getUid();
        if (uid == null) {
            return R.fail("请先登录");
        }
        novelComment.setUserId(uid);
        int i = novelCommentMapper.insert(novelComment);
        if (i != 1) {
            return R.fail("发布小说评论失败");
        }
        return R.ok("发布小说评论成功");
    }

    /**
     * 回复小说某用户的评论,需要登录
     *
     * @param novelCommentReply
     * @return
     */
    @Override
    public R<String> commentReply(NovelCommentReply novelCommentReply) {
        //获取登录用户信息
        AuthInfo authInfo = AppInterceptor.get();
        Integer uid = authInfo.getUid();
        if (uid == null) {
            return R.fail("请先登录");
        }
        novelCommentReply.setUserId(uid);
        int i = novelCommentReplyMapper.insert(novelCommentReply);
        if (i != 1) {
            return R.fail("回复评论失败");
        }
        return R.ok("回复评论成功");
    }


    /**
     * 获取某部小说评论的回复数量
     *
     * @param commentId
     * @return
     */
    public Long getCommentReplyCount(Integer commentId) {

        return novelCommentReplyMapper.selectCount(new QueryWrapper<NovelCommentReply>().eq("comment_id", commentId));
    }


    /**
     * 检验评论是否点赞，是否是本人
     *
     * @param userId
     * @param commentId
     * @return
     */
    public ExInfo getCommentExInfo(Integer userId, Integer commentId) {
        ExInfo exInfo = ExInfo.getInstance();
        //获取登录信息
        AuthInfo authInfo = AppInterceptor.get();
        Integer uid = authInfo.getUid();
        if (uid == null) {
            return exInfo;
        }
        if (uid.equals(userId)) {
            exInfo.setMine(true);
        }
        if (novelCommentPraisesMapper.isPraised(uid, commentId) != null) {
            exInfo.setPraised(true);
        }

        return exInfo;
    }

    /**
     * 检验评论回复是否点赞，是否是本人
     *
     * @param userId
     * @param replyId
     * @return
     */
    public ExInfo getReplyExInfo(Integer userId, Integer replyId) {
        ExInfo exInfo = ExInfo.getInstance();
        //获取登录信息
        AuthInfo authInfo = AppInterceptor.get();
        Integer uid = authInfo.getUid();
        if (uid == null) {
            return exInfo;
        }
        if (uid.equals(userId)) {
            exInfo.setMine(true);
        }
        if (novelCommentReplyPraisesMapper.isPraised(uid, replyId) != null) {
            exInfo.setPraised(true);
        }


        return exInfo;
    }


    /**
     * 检验书架是否已存在
     *
     * @param novelId
     * @param uid
     * @return
     */
    public Boolean isShelf(Integer novelId, Integer uid) {

        NovelShelf novelShelf = novelShelfMapper.getShelf(novelId, uid);
        return novelShelf != null;
    }
}
